'use strict';

const { Controller } = require('egg');
const fs = require('fs');
const path = require('path');
const moment = require('moment');
const mkdirp = require('mkdirp');
const sendToWormhole = require('stream-wormhole');

/**
 * @Controller 文件上传接口
 */

class FileController extends Controller {

    /**
     * @summary 测试
     * @description 测试
     * @router get /home/index
     * @response 200 baseResponse 成功
     */
    async index(){
        this.ctx.body = 'hi egg'
    }

    /**
     * @summary 创建任务
     * @description 创建任务
     * @router post /api/task/create
     * @response 200 baseResponse 成功
     */
    async taskCreate(){
        const { ctx } = this;
        const payload = ctx.request.body || {};
        let { task, type } = payload;  //是一个图片组
        let data = task.map(item=>{
            return { url: item, type }
        })
        let t = await ctx.model.transaction();
        
        try{
            await ctx.model.Task.bulkCreate(data, {
                transaction: t
            })
            await t.commit();
            ctx.helper.success({ ctx, res: null })
        }catch(e){
            await t.rollback();
            ctx.helper.error({ ctx, msg: '创建失败' })
        }
    }

    /**
     * @summary 上传单文件
     * @description 上传单文件
     * @router post /api/upload/single
     * @response 200 baseResponse 成功
     */
    async upload(){
        const { ctx } = this;
        const stream = await ctx.getFileStream(); // 获取上传文件流
        if (!stream.filename) {
            return ctx.helper.error({ ctx, msg: '上传文件流错误'})
        }
         // 1. 定义保存路径和文件名
        const day = moment().format('YYYYMMDD');
        const destDir = path.join(this.config.static.dir, 'upload', day); 
        await mkdirp.mkdirp(destDir);  // 确保目录存在，不存在会自动创建
        const timestamp = Date.now();
        const randomStr = Math.random().toString(36).substr(2, 8);
        const extname = path.extname(stream.filename);
        const filename = `${timestamp}${randomStr}${extname}`;
        const targetPath = path.join(destDir, filename); //拼接出文件的完整目录
        try {
            // 2. 创建写入流
            const writeStream = fs.createWriteStream(targetPath);
            
            // 3. 通过管道将文件流导入到写入流
            await new Promise((resolve, reject) => {
                stream.pipe(writeStream);
                stream.on('end', resolve);
                stream.on('error', err => {
                    sendToWormhole(stream); // 出错时消费掉剩余数据
                    writeStream.destroy(err);
                    reject(err);
                });
                writeStream.on('error', reject);
            });

            // 4. 返回成功信息
            const fileUrl = `upload/${day}/${filename}`;
            ctx.body = {
                code: 200,
                msg: '上传成功',
                data: { url: fileUrl },
            };
            } catch (err) {
                ctx.logger.error('文件流上传失败: %j', err);
                // 尝试清理可能已部分写入的文件
                if (await fs.exists(targetPath)) {
                    await fs.unlink(targetPath);
                }
                return ctx.helper.error({ ctx, msg: '文件上传失败'})
            }
        
    }



}

module.exports = FileController;